import com.sun.java.swing.plaf.windows.WindowsToggleButtonUI;

//一、父类的成员访问
//1.子类访问父类的成员变量
//1.(1).子类和父类不存在同名变量
class Base{
    public int a;
    public int b;

}
class Derived extends Base{
    public int c;

    public void md(){
        a = 10;
        b = 20;
        c = 30;
        System.out.println(a + b + c);
    }
    //那么现在成员变量的分布现在就是可以理解分为两个布局，一个布局是继承父类的a和b，一个布局是子类的c
}
//1.(2).子类和父类存在同名变量
class Base1{
    public int a = 1;
    public int b = 2;
    public int d = 99;

}
class Derived1 extends Base1{
    public int c = 3;
    public int a = 4;
    public void md1() {
        System.out.println(super.a);
//        System.out.println(a);
//        System.out.println(b);
//        System.out.println(c);
        System.out.println(this.a);
        System.out.println(this.b);
        System.out.println(this.c);
        System.out.println(this.d);
        System.out.println("==================");
        System.out.println(super.a);
        System.out.println(super.b);
        System.out.println(super.d);
        //这是用来访问父类的成员变量
        System.out.println(this.a);//同名变量优先访问子类
        System.out.println(this.b);
        System.out.println(this.d);
        System.out.println(this.c);
        //这个this访问的是所有的成员变量
    }
    //那么现在的结果就是1 4 2 3
    //那么现在的成员变量的布局也分为了两个阶段，一个布局就是继承父类的a和b,一个布局就是子类中的a和c
    /*
    System.out.println(a);
    System.out.println(b);
    System.out.println(c);、
    就是代表了this
     */

    //this可以访问子类中的所有的成员变量包括继承了父类的成员变量，super用来访问子类继承父类中的成员变量（父类成员变量被封装不可以）

}

//总结1：
//当子类和父类成员变量同名的时候，在子类中访问这个同名变量，访问的是子类自己的！优先访问子类自己的
//如果一定访问父类的同名变量，那么就需要一个关键字super，比如我要访问了父类中的a，那么就需要用到了super.a这个操作

//总结2：
//this访问的时候不仅访问父类也可以访问子类的
//当使用this访问父类和子类同名的成员变量的时候，子类优先访问！！！
//super只能访问从父类继承过来的成员变量
//也可以理解为：现在子类，子类没有那么就在父类找，父类也没有，编译报错

//关于对super的关键字的理解：
//它只是一个关键字，有些书上说，它代表了父类对象的引用，其实都是错的！！！
//严格地说：就是一个关键字！！！提高代码的可读性！让别人看到这样就知道这是访问父类的关键字


//2.子类访问父类的成员方法
//2.(1).子类和父类不存在同名成员方法

class Base2{
    public void func1(){
        System.out.println("func1()");
    }
}
class Derived2 extends Base2{
    public void func2(){
        System.out.println("func2()");
    }
    public void testFunc(){
        func1();;
        func2();
    }
}
//总结：成员方法没有同名时，在子类方法中或者通过子类对象访问方法时，则优先访问自己的，自己没有时
//再到父类中找，如果父类中也没有则报错。

class Base3{
    public void func1(){
        System.out.println("func1()");
    }
}
class Derived3 extends Base2{
    public void func2(){
        System.out.println("func2()");
    }
    public void func1(int a){
        System.out.println("func1(int)");
    }
    public void testFunc(){
        func1(10);//子类的
        func1();
        func2();
        super.func1();//父类的
    }
    //所以传参数的时候寻找到的是子类中的func1，当没有传参数的时候，它会找寻到父类的func1
    //其实这也是一种重载，参数的不同，名字一样，所以会根据参数来找寻特定的方法

    public void func1() {
        System.out.println("func1(子类的)");
    }//当方法构成了重写，也就是参数相同名字相同的时候，那么会每次都去优先访问子类的
}

/*
通过子类对象访问父类与子类中不同名方法时，优先在子类中找，找到则访问，否则在父类中找，找到则访问，否则编译报错。
通过派生类对象访问父类与子类同名方法时，如果父类和子类同名方法的参数列表不同(重载)，
根据调用方法适传递的参数选择合适的方法访问，如果没有则报错；
 */

public class Test {
    public static void main(String[] args) {
//        Derived derived = new Derived();
//        derived.md();
//        Derived1 derived1 = new Derived1();
//        derived1.md1();
//
        Derived3 derived3 = new Derived3();
        derived3.testFunc();
    }
//先简单讲述一下super
//这节我们在父与子中有重名的时候需要用到了super.data访问父类的成员变量，super.func()访问父类的成员方法
//该关键字主要作用：在子类方法中访问父类的成员。
//所以super在当前类当中使用，那么当前类一定是子类，因为要访问父类的成员属性和行为

//super和this一样不能使用在静态方法中，只能非静态方法中使用

//留一个：面试问题：super 和 this 有什么区别 ？

}
/**
 * 总结：
 * 什么是继承：共性的抽取，用extends
 * 为什么要继承：要达到代码的复用
 * 子类继承父类的那些都有什么？，还有重名的该怎么办？
 */
